﻿using System;
using System.Text;

public class ByteBuffer
{
    public const int BO_BIG_ENDIAN = 0;
    public const int BO_LITTLE_ENDIAN = 1;
    private short[] buf;
    private int byteOrder;
    private int curPos;
    public const bool DEBUG = false;
    private bool expandable;
    private int expandBy;
    private bool hasBeenErrors;
    private int size;

    public ByteBuffer(int size, int byteOrdering)
    {
        this.expandable = true;
        this.expandBy = 0x1000;
        if (size < 1)
        {
            size = 1;
        }
        this.buf = new short[size];
        this.size = size;
        this.byteOrder = byteOrdering;
        this.curPos = 0;
        this.hasBeenErrors = false;
    }

    public ByteBuffer(sbyte[] content, int byteOrdering)
    {
        this.expandable = true;
        this.expandBy = 0x1000;
        try
        {
            this.buf = new short[content.Length];
            for (int i = 0; i < content.Length; i++)
            {
                this.buf[i] = (short) (content[i] & 0xff);
            }
            this.size = content.Length;
            this.byteOrder = byteOrdering;
            this.curPos = 0;
            this.hasBeenErrors = false;
        }
        catch (Exception)
        {
        }
    }

    public static ByteBuffer asciiDecode(ByteBuffer buf)
    {
        return null;
    }

    public static ByteBuffer asciiEncode(ByteBuffer buf)
    {
        short[] numArray = buf.buf;
        sbyte[] content = new sbyte[buf.Size * 2];
        int index = 0;
        for (int i = 0; i < numArray.Length; i++)
        {
            int num2 = numArray[i];
            content[index] = (sbyte) ((0x41 + num2) & 15);
            content[index + 1] = (sbyte) ((0x41 + (num2 >> 4)) & 15);
            index += 2;
        }
        return new ByteBuffer(content, 0);
    }

    public virtual void clear()
    {
        for (int i = 0; i < this.buf.Length; i++)
        {
            this.buf[i] = 0;
        }
        this.curPos = 0;
    }

    public virtual void crop()
    {
        if ((this.curPos > 0) && (this.curPos < this.buf.Length))
        {
            short[] destinationArray = new short[this.curPos];
            Array.Copy(this.buf, 0, destinationArray, 0, this.curPos);
            this.buf = destinationArray;
        }
    }

    private void error()
    {
        this.hasBeenErrors = true;
    }

    public virtual void expand()
    {
        this.expand(this.expandBy);
    }

    public virtual void expand(int byHowMuch)
    {
        this.resize(this.size + byHowMuch);
    }

    private short[] expandShortArray(short[] array, int size)
    {
        short[] destinationArray = new short[array.Length + size];
        if (size > 0)
        {
            Array.Copy(array, 0, destinationArray, 0, array.Length);
            return destinationArray;
        }
        Array.Copy(array, 0, destinationArray, 0, destinationArray.Length);
        return destinationArray;
    }

    public virtual void fill(sbyte value_Renamed)
    {
        for (int i = 0; i < this.size; i++)
        {
            this.buf[i] = value_Renamed;
        }
    }

    public virtual bool fillRange(int start, int length, sbyte value_Renamed)
    {
        if (this.inRange(start, length))
        {
            for (int i = start; i < (start + length); i++)
            {
                this.buf[i] = value_Renamed;
            }
            return true;
        }
        this.error();
        return false;
    }

    public virtual void goTo(int position)
    {
        if (this.inRange(position))
        {
            this.curPos = position;
        }
        else
        {
            this.error();
        }
    }

    public virtual bool hasHadErrors()
    {
        return this.hasBeenErrors;
    }

    public virtual bool inRange(int pos)
    {
        if ((pos >= 0) && (pos < this.size))
        {
            return true;
        }
        if (this.expandable)
        {
            this.expand(Math.Max((pos + 1) - this.size, this.expandBy));
            return true;
        }
        return false;
    }

    public virtual bool inRange(int pos, int length)
    {
        if ((pos >= 0) && ((pos + (length - 1)) < this.size))
        {
            return true;
        }
        if (this.expandable)
        {
            this.expand(Math.Max((pos + length) - this.size, this.expandBy));
            return true;
        }
        return false;
    }

    public virtual void move(int howFar)
    {
        this.curPos += howFar;
        if (!this.inRange(this.curPos))
        {
            this.curPos = this.size - 1;
        }
    }

    public virtual bool putBoolean(bool b)
    {
        bool flag = this.putBoolean(b, this.curPos);
        this.move(1);
        return flag;
    }

    public virtual bool putBoolean(bool b, int pos)
    {
        if (b)
        {
            return this.putByte(1, pos);
        }
        return this.putByte(0, pos);
    }

    public virtual bool putByte(short var)
    {
        if (this.inRange(this.curPos, 1))
        {
            this.buf[this.curPos] = var;
            this.move(1);
            return true;
        }
        this.error();
        return false;
    }

    public virtual bool putByte(short var, int pos)
    {
        if (this.inRange(pos, 1))
        {
            this.buf[pos] = var;
            return true;
        }
        this.error();
        return false;
    }

    public virtual bool putByteArray(short[] arr)
    {
        if (arr == null)
        {
            return false;
        }
        if ((this.buf.Length - this.curPos) < arr.Length)
        {
            this.resize(this.curPos + arr.Length);
        }
        for (int i = 0; i < arr.Length; i++)
        {
            this.buf[this.curPos + i] = (byte) arr[i];
        }
        this.curPos += arr.Length;
        return true;
    }

    public virtual bool putChar(char var)
    {
        bool flag = this.putChar(var, this.curPos);
        if (flag)
        {
            this.move(2);
        }
        return flag;
    }

    public virtual bool putChar(char var, int pos)
    {
        int num = var;
        if (this.inRange(pos, 2))
        {
            if (this.byteOrder == 0)
            {
                this.buf[pos] = (short) ((num >> 8) & 0xff);
                this.buf[pos + 1] = (short) (num & 0xff);
            }
            else
            {
                this.buf[pos + 1] = (short) ((num >> 8) & 0xff);
                this.buf[pos] = (short) (num & 0xff);
            }
            return true;
        }
        this.error();
        return false;
    }

    public virtual bool putCharAscii(char var)
    {
        bool flag = this.putCharAscii(var, this.curPos);
        if (flag)
        {
            this.move(1);
        }
        return flag;
    }

    public virtual bool putCharAscii(char var, int pos)
    {
        if (this.inRange(pos))
        {
            this.buf[pos] = (short) var;
            return true;
        }
        this.error();
        return false;
    }

    public virtual bool putInt(int var)
    {
        bool flag = this.putInt(var, this.curPos);
        if (flag)
        {
            this.move(4);
        }
        return flag;
    }

    public virtual bool putInt(int var, int pos)
    {
        if (this.inRange(pos, 4))
        {
            if (this.byteOrder == 0)
            {
                this.buf[pos] = (short) ((var >> 0x18) & 0xff);
                this.buf[pos + 1] = (short) ((var >> 0x10) & 0xff);
                this.buf[pos + 2] = (short) ((var >> 8) & 0xff);
                this.buf[pos + 3] = (short) (var & 0xff);
            }
            else
            {
                this.buf[pos + 3] = (short) ((var >> 0x18) & 0xff);
                this.buf[pos + 2] = (short) ((var >> 0x10) & 0xff);
                this.buf[pos + 1] = (short) ((var >> 8) & 0xff);
                this.buf[pos] = (short) (var & 0xff);
            }
            return true;
        }
        this.error();
        return false;
    }

    public virtual bool putShort(short var)
    {
        bool flag = this.putShort(var, this.curPos);
        if (flag)
        {
            this.move(2);
        }
        return flag;
    }

    public virtual bool putShort(short var, int pos)
    {
        if (this.inRange(pos, 2))
        {
            if (this.byteOrder == 0)
            {
                this.buf[pos] = (short) ((var >> 8) & 0xff);
                this.buf[pos + 1] = (short) (var & 0xff);
            }
            else
            {
                this.buf[pos + 1] = (short) ((var >> 8) & 0xff);
                this.buf[pos] = (short) (var & 0xff);
            }
            return true;
        }
        this.error();
        return false;
    }

    public virtual bool putShortArray(short[] arr)
    {
        if (arr == null)
        {
            return false;
        }
        if ((this.buf.Length - this.curPos) < (arr.Length * 2))
        {
            this.resize(this.curPos + (arr.Length * 2));
        }
        if (this.byteOrder == 0)
        {
            for (int i = 0; i < arr.Length; i++)
            {
                this.buf[this.curPos] = (short) ((arr[i] >> 8) & 0xff);
                this.buf[this.curPos + 1] = (short) (arr[i] & 0xff);
                this.curPos += 2;
            }
        }
        else
        {
            for (int j = 0; j < arr.Length; j++)
            {
                this.buf[this.curPos + 1] = (short) ((arr[j] >> 8) & 0xff);
                this.buf[this.curPos] = (short) (arr[j] & 0xff);
                this.curPos += 2;
            }
        }
        return true;
    }

    public virtual bool putString(string var)
    {
        bool flag = this.putString(var, this.curPos);
        if (flag)
        {
            this.move(2 * var.Length);
        }
        return flag;
    }

    public virtual bool putString(string var, int pos)
    {
        char[] chArray = var.ToCharArray();
        if (this.inRange(pos, var.Length * 2))
        {
            for (int i = 0; i < var.Length; i++)
            {
                short num = (short) chArray[i];
                this.buf[pos] = (short) ((num >> 8) & 0xff);
                this.buf[pos + 1] = (short) (num & 0xff);
                pos += 2;
            }
            return true;
        }
        this.error();
        return false;
    }

    public virtual bool putStringAscii(string var)
    {
        bool flag = this.putStringAscii(var, this.curPos);
        if (flag)
        {
            this.move(var.Length);
        }
        return flag;
    }

    public virtual bool putStringAscii(string var, int pos)
    {
        char[] chArray = var.ToCharArray();
        if (this.inRange(pos, var.Length))
        {
            for (int i = 0; i < var.Length; i++)
            {
                this.buf[pos] = (short) chArray[i];
                pos++;
            }
            return true;
        }
        this.error();
        return false;
    }

    public virtual bool readBoolean()
    {
        bool flag = this.readBoolean(this.curPos);
        this.move(1);
        return flag;
    }

    public virtual bool readBoolean(int pos)
    {
        return (this.readByte(pos) == 1);
    }

    public virtual short readByte()
    {
        short num = this.readByte(this.curPos);
        this.move(1);
        return num;
    }

    public virtual short readByte(int pos)
    {
        if (this.inRange(pos))
        {
            return this.buf[pos];
        }
        this.error();
        throw new IndexOutOfRangeException();
    }

    public virtual bool readByteArray(short[] arr)
    {
        if (arr == null)
        {
            return false;
        }
        if ((this.buf.Length - this.curPos) < arr.Length)
        {
            return false;
        }
        for (int i = 0; i < arr.Length; i++)
        {
            arr[i] = this.buf[this.curPos + i];
        }
        this.curPos += arr.Length;
        return true;
    }

    public virtual char readChar()
    {
        char ch = this.readChar(this.curPos);
        this.move(2);
        return ch;
    }

    public virtual char readChar(int pos)
    {
        if (this.inRange(pos, 2))
        {
            return (char) ((ushort) this.readShort(pos));
        }
        this.error();
        throw new IndexOutOfRangeException();
    }

    public virtual char readCharAscii()
    {
        char ch = this.readCharAscii(this.curPos);
        this.move(1);
        return ch;
    }

    public virtual char readCharAscii(int pos)
    {
        if (this.inRange(pos, 1))
        {
            return (char) (this.readByte(pos) & 0xff);
        }
        this.error();
        throw new IndexOutOfRangeException();
    }

    public virtual int readInt()
    {
        int num = this.readInt(this.curPos);
        this.move(4);
        return num;
    }

    public virtual int readInt(int pos)
    {
        int num = 0;
        if (this.inRange(pos, 4))
        {
            if (this.byteOrder == 0)
            {
                num |= this.buf[pos] << 0x18;
                num |= this.buf[pos + 1] << 0x10;
                num |= this.buf[pos + 2] << 8;
                return (num | this.buf[pos + 3]);
            }
            num |= this.buf[pos + 3] << 0x18;
            num |= this.buf[pos + 2] << 0x10;
            num |= this.buf[pos + 1] << 8;
            return (num | this.buf[pos]);
        }
        this.error();
        throw new IndexOutOfRangeException();
    }

    public virtual short readShort()
    {
        short num = this.readShort(this.curPos);
        this.move(2);
        return num;
    }

    public virtual short readShort(int pos)
    {
        if (this.inRange(pos, 2))
        {
            if (this.byteOrder == 0)
            {
                return (short) ((this.buf[pos] << 8) | this.buf[pos + 1]);
            }
            return (short) ((this.buf[pos + 1] << 8) | this.buf[pos]);
        }
        this.error();
        throw new IndexOutOfRangeException();
    }

    public virtual string readString(int length)
    {
        if (length > 0)
        {
            string str = this.readString(this.curPos, length);
            this.move(str.Length * 2);
            return str;
        }
        return new StringBuilder("").ToString();
    }

    public virtual string readString(int pos, int length)
    {
        if (!this.inRange(pos, length * 2) || (length <= 0))
        {
            throw new IndexOutOfRangeException();
        }
        char[] chArray = new char[length];
        for (int i = 0; i < length; i++)
        {
            chArray[i] = this.readChar(pos + (i * 2));
        }
        return new string(chArray);
    }

    public virtual string readStringAscii(int length)
    {
        string str = this.readStringAscii(this.curPos, length);
        this.move(str.Length);
        return str;
    }

    public virtual string readStringAscii(int pos, int length)
    {
        if (!this.inRange(pos, length) || (length <= 0))
        {
            throw new IndexOutOfRangeException();
        }
        char[] chArray = new char[length];
        for (int i = 0; i < length; i++)
        {
            chArray[i] = this.readCharAscii(pos + i);
        }
        return new string(chArray);
    }

    public virtual string readStringAsciiWithShortLength()
    {
        string str = this.readStringAsciiWithShortLength(this.curPos);
        this.move(str.Length + 2);
        return str;
    }

    public virtual string readStringAsciiWithShortLength(int pos)
    {
        if (!this.inRange(pos, 2))
        {
            throw new IndexOutOfRangeException();
        }
        short length = this.readShort(pos);
        if (length > 0)
        {
            return this.readStringAscii(pos + 2, length);
        }
        return new StringBuilder("").ToString();
    }

    public virtual string readStringWithShortLength()
    {
        string str = this.readStringWithShortLength(this.curPos);
        this.move((str.Length * 2) + 2);
        return str;
    }

    public virtual string readStringWithShortLength(int pos)
    {
        if (!this.inRange(pos, 2))
        {
            throw new IndexOutOfRangeException();
        }
        short length = this.readShort(pos);
        if (length > 0)
        {
            return this.readString(pos + 2, length);
        }
        return new StringBuilder("").ToString();
    }

    public virtual void resize(int length)
    {
        short[] destinationArray = new short[length];
        Array.Copy(this.buf, 0, destinationArray, 0, Math.Min(length, this.size));
        this.buf = destinationArray;
        this.size = length;
    }

    public virtual void resizeToCurrentPos()
    {
        this.resize(this.curPos);
    }

    public override string ToString()
    {
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < (this.size - 1); i += 2)
        {
            short num = (short) ((this.buf[i] << 8) | this.buf[i + 1]);
            builder.Append((char) ((ushort) num));
        }
        return builder.ToString();
    }

    public virtual string toStringAscii()
    {
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < this.size; i++)
        {
            builder.Append((char) ((ushort) this.buf[i]));
        }
        return builder.ToString();
    }

    public virtual int ByteOrder
    {
        set
        {
            if ((value >= 0) && (value < 2))
            {
                this.byteOrder = value;
            }
        }
    }

    public virtual bool Expandable
    {
        set
        {
            this.expandable = value;
        }
    }

    public virtual int ExpandBy
    {
        set
        {
            if (value > 0x400)
            {
                this.expandBy = value;
            }
        }
    }

    public virtual int Pos
    {
        get
        {
            return this.curPos;
        }
    }

    public virtual int Size
    {
        get
        {
            return this.size;
        }
    }
}

